
#include "Shell.h"

// Get input from ->
ifstream ifs("test.sh");

// Send output to ->
ofstream ofs("log.txt");



int main(int argc, char * argv[]) {
	Shell* shell = new Shell();
	return 0;
}

Shell::Shell() {
	Pipe* pipe;
	while ((pipe = startParsing()) != 0) {
		executeCommands(pipe);
	}
}

Shell::~Shell() {

}

Pipe* Shell::startParsing() {
	bool more = true;
	bool redirectInput = false;
	bool redirectOutput = false;
	bool append = false;

	Token * tp; // "huidige" token

	Pipe* currentPipe = new Pipe();
	Command* currentCommand = 0;

	while(more) {
		tp = nextToken( ifs ); // vraag eerst volgende token

		// vertel wat we gekregen hebben
		ofs << "token:" << tp->getType() << "\t";
//		cout << "token:" << tp->getType() << "\t" << endl;

		// kies een actie
		switch (tp->getType()) {
			case Token::END:

			ofs << "END";
			return 0;
			break;
			case Token::EOL:
//			more = false;
			ofs << "NEWLINE" << endl;
			return currentPipe;
			break;
			case Token::SEQUENCE:
			return currentPipe;
			ofs << ";";
			break;
			case Token::PIPE:
			currentCommand = 0;
			ofs << "|";
			break;
			case Token::APPEND:
			append = true;
			ofs << ">>";
			break;
			case Token::INPUT:
			redirectInput = true;
			ofs << "<";
			break;
			case Token::OUTPUT:
			redirectOutput = true;
			ofs << ">";
			break;
			case Token::WORD:
			if ((tp->getText() == "logout") || (tp->getText() == "exit")) {
				ofs << "EINDE";
				return 0;
			}
			else if (redirectOutput) {
				redirectOutput = false;
				currentCommand->setIORedirectionOutput(tp->getText());
			}
			else if (redirectInput) {
				redirectInput = false;
				currentCommand->setIORedirectionInput(tp->getText());
				// Geen IORedirection dus een argument
			}
			else if (append) {
				append = false;
				currentCommand->setIORedirectionOutput(tp->getText());
				currentCommand->setAppend();
			}
			else if (currentCommand == 0) {
				// Dit is een commando
				ofs << "NC ";
				currentCommand = new Command(tp->getText());
				currentPipe->addCommand(currentCommand);
			}
			else {
				// Anders is dit een argument van het huidige commando
				currentCommand->addArgument( tp->getText() );
				ofs << "NA ";
			}

			ofs << "WORD=|" << tp->getText() << "|";
			break;

			default:
			ofs << "?"<< tp->getText() << "?";
			cout << "?"<< tp->getText() << "?" << endl;
			break;
		}
		ofs << endl;

		delete tp;
	}
	return currentPipe;
}

void Shell::executeCommands(Pipe* pipe) {

	pid_t childpid;
	int fd_in = -1;
	int fd_out;
	int index = 0;

	for (list<Command*>::iterator iter = pipe->getCommands()->begin(); iter != pipe->getCommands()->end(); iter++, index++) {
		Command* c = (*iter);
		cout << c->getIORedirectionInput();

		int fd[2];
		pid_t childpid;


		//Code to direct from a file input
		if(c->getIORedirectionInput() != "") {
			fd_in = open(c->getIORedirectionInput().c_str(), O_RDONLY);
		}

		//Code to direct to a file output (create)
		if (c->getIORedirectionOutput() != "") {
			fd_out = open(c->getIORedirectionOutput().c_str(), O_WRONLY | O_CREAT, 0644);
		}

		//Code to direct to a file output (append)
		else if (c->getAppend()) {
			fd_out = open(c->getIORedirectionOutput().c_str(), O_WRONLY | O_APPEND | O_CREAT, 0644);
		}


//		//No file redirection needed, leave the input and output as they are
//		else {
//			//if we have more commands, setup a new pipe
//			if (index + 1 < commands->size()) {
//				if (debug) {
//					cout << "We have more commands" << endl;
//				}
//				pipe(fd);
//				fd_out = fd[1];
//			}
//			//No more commands, this is the end
//			else {
//				if (debug) {
//					cout << "The end of the commands" << endl;
//				}
//				fd_out = -1;
//			}
//		}
//
//		// fork new pid
//		childpid = fork();
//
//		// check if something went wrong (pid negative)
//		if (childpid < 0) {
//			perror("fork");
//			exit(1);
//		}
//
//		// pid 0: child process
//		if (childpid == 0) {
//			// pipe in
//			if (fd_in != -1 && fd_in != 0) {
//				if (debug) {
//					cout << "--> Pipe in" << endl;
//				}
//				dup2(fd_in, 0);
//				close(fd_in);
//			}
//
//			// pipe out
//			if (fd_out != -1 && fd_in != 1) {
//				if (debug) {
//					cout << "--> Pipe out" << endl;
//				}
//				dup2(fd_out, 1);
//				close(fd_out);
//			}
			c->exec();
//			exit(-1);
//		}
//		// parent process
//		else {
//			if (debug) {
//				cout << "waiting for process" << endl;
//			}
//			//waitpid(childpid,NULL,0);
//			if (debug) {
//				cout << "process done" << endl;
//			}
//		}
//		//waitpid(childpid,NULL,0);
//
//		close(fd_in);
//		close(fd_out);
//
//		// set up stdin for next command
//		fd_in = fd[0];
//	}
//
//	// wait till processes are done
//	waitpid(childpid, NULL, 0);
//
//	//clean the command list
//	commands->erase(commands->begin(), commands->end());
//
//	//add new clean command
//	newCommand();
//	redirectDirection = "";
//	redirectFile = "";

} }
